﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using GMPP.Texture;
using SHVS.Media;
using VLIB28D.Geometry3D;
using VLIB2D.Geometry2D;

namespace GMPP.Import
{


    public class ObjImporter : Importer
    {

     private int currentLineNo;

     /// <summary>
     /// Gets or sets a value indicating whether to ignore errors.
     /// </summary>
     /// <value><c>true</c> if errors should be ignored; <c>false</c> if errors should throw an exception.</value>
     /// <remarks>
     /// The default value is on (true).
     /// </remarks>
     public bool IgnoreErrors { get; set; }

     /// <summary>
     /// Gets or sets the normals.
     /// </summary>
     private IList<Vector3D> Normals { get; set; }

     /// <summary>
     /// Gets or sets the points.
     /// </summary>
     private IList<Point3D> Points { get; set; }

    

     /// <summary>
     /// Gets or sets the texture coordinates.
     /// </summary>
     private IList<Point2D> TextureCoordinates { get; set; }


        public ObjImporter(String path)
        {
            IgnoreErrors = true;
            this.path = path;
            this.Init();

            if (Extension.ToUpper() == "OBJ")
            {
                // Read(path);//解析方法！！
            }
            else
            {
                throw (new Exception("文件类型不是OBJ"));
            }
        }



        public void Read()
        {
            using (sr)
            {
                this.currentLineNo = 0;
                while (!sr.EndOfStream)
                {
                    this.currentLineNo++;
                    var line = this.sr.ReadLine();
                    if (line == null)
                    {
                        break;
                    }

                    line = line.Trim();
                    if (line.StartsWith("#") || line.Length == 0)
                    {
                        continue;
                    }

                    string keyword, values;
                    SplitLine(line, out keyword, out values);

                    switch (keyword.ToLower())
                    {
                        // Vertex data
                        case "v": // geometric vertices
                            this.AddVertex(values);
                            break;
                        case "vt": // texture vertices
                            this.AddTexCoord(values);
                            break;
                        case "vn": // vertex normals
                            this.AddNormal(values);
                            break;
                        case "vp": // parameter space vertices
                        case "cstype": // rational or non-rational forms of curve or surface type: basis matrix, Bezier, B-spline, Cardinal, Taylor
                        case "degree": // degree
                        case "bmat": // basis matrix
                        case "step": // step size
                            // not supported
                            break;

                        // Elements
                        case "f": // face
                            this.AddFace(values);
                            break;
                        case "p": // point
                        case "l": // line
                        case "curv": // curve
                        case "curv2": // 2D curve
                        case "surf": // surface
                            // not supported
                            break;

                        // Free-form curve/surface body statements
                        case "parm": // parameter name
                        case "trim": // outer trimming loop (trim)
                        case "hole": // inner trimming loop (hole)
                        case "scrv": // special curve (scrv)
                        case "sp":  // special point (sp)
                        case "end": // end statement (end)
                            // not supported
                            break;

                        // Connectivity between free-form surfaces
                        case "con": // connect
                            // not supported
                            break;

                        // Grouping
                        case "g": // group name
                            //this.AddGroup(values);
                            break;
                        case "s": // smoothing group
                           // this.SetSmoothingGroup(values);
                            break;
                        case "mg": // merging group
                            break;
                        case "o": // object name
                            // not supported
                            break;

                        // Display/render attributes
                        case "mtllib": // material library
                           // this.LoadMaterialLib(values);
                            break;
                        case "usemtl": // material name
                           // this.EnsureNewMesh();

                           // this.SetMaterial(values);
                            break;
                        case "usemap": // texture map name
                          //  this.EnsureNewMesh();

                            break;
                        case "bevel": // bevel interpolation
                        case "c_interp": // color interpolation
                        case "d_interp": // dissolve interpolation
                        case "lod": // level of detail
                        case "shadow_obj": // shadow casting
                        case "trace_obj": // ray tracing
                        case "ctech": // curve approximation technique
                        case "stech": // surface approximation technique
                            // not supported
                            break;
                    }
                }
            }

        }

        private static double DoubleParse(string input)
        {
            return double.Parse(input, CultureInfo.InvariantCulture);
        }


        private static IList<double> Split(string input)
        {
            input = input.Trim();
            var fields = new string[5];// input.SplitOnWhitespace();
            var result = new double[fields.Length];
            for (int i = 0; i < fields.Length; i++)
            {
                result[i] = DoubleParse(fields[i]);
            }

            return result;
        }

        private static void SplitLine(string line, out string keyword, out string arguments)
        {
            int idx = line.IndexOf(' ');
            if (idx < 0)
            {
                keyword = line;
                arguments = null;
                return;
            }

            keyword = line.Substring(0, idx);
            arguments = line.Substring(idx + 1);
        }


        private void AddVertex(string values)
        {
            var fields = Split(values);
            this.Points.Add(new Point3D(fields[0], fields[1], fields[2]));
        }

        private void AddTexCoord(string values)
        {
            var fields = Split(values);
            ///原始代码为什么要“1-”
            //this.TextureCoordinates.Add(new Point2D(fields[0], 1 - fields[1]));
            this.TextureCoordinates.Add(new Point2D(fields[0],   fields[1]));
        }

        private void AddNormal(string values)
        {
            var fields = Split(values);
            this.Normals.Add(new Vector3D(fields[0], fields[1], fields[2]));
        }

        private void AddFace(string values)
        { 
             
        }


    }

}
